package com.kwin.rpcclient.scan;

import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;

import com.kwin.rpcclient.holder.ConnManage;
import com.kwin.rpccommon.annotation.RpcClient;
import com.kwin.rpccommon.dto.Request;
import com.kwin.rpccommon.dto.Response;
import com.kwin.rpccommon.util.SnowflakeIdWorker;
import io.netty.channel.Channel;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;


import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

/**
 * @author : wangkai
 * @version V1.0
 * @Package com.kwin.rpc.config.rpc
 * @Description:
 * @date 2021年06月22日 15:18
 **/
@Slf4j
//@Component
public class RpcFactory<T> implements InvocationHandler {


    
//    @Autowired
//    NettyClient client;
    
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        
        Class clzz = method.getDeclaringClass();
        RpcClient rpcClient = (RpcClient)clzz.getAnnotation(RpcClient.class);
        rpcClient.url();
        rpcClient.value();
        log.info("url is {}, val is {}", rpcClient.url(), rpcClient.value());
        ConnManage.updateConnServer(rpcClient.value(), Arrays.asList(rpcClient.url().clone()));
        
        
        Request request = new Request();
        request.setClassName(method.getDeclaringClass().getName());
        request.setMethodName(method.getName());
        request.setParameters(args);
        request.setParameterTypes(method.getParameterTypes());
        request.setId(SnowflakeIdWorker.getInstance().nextId() + "");
    
//        Object result = NettySocketHolder.send(req);
        // TODO:
        Object result = ConnManage.send(rpcClient.value(), request);
        Class<?> returnType = method.getReturnType();
        
        Response response = JSON.parseObject(result.toString(), Response.class);
        if (response.getCode() == "1"){
            throw new Exception(response.getMsg());
        }
        // 返回数据类型
        if (returnType.isPrimitive() || String.class.isAssignableFrom(returnType)){
            return response.getData();
        }else if (Collection.class.isAssignableFrom(returnType)){
            return JSONArray.parseArray(response.getData().toString(),Object.class);
        }else if(Map.class.isAssignableFrom(returnType)){
            return JSON.parseObject(response.getData().toString(),Map.class);
        }else{
            Object data = response.getData();
            return JSONObject.parseObject(data.toString(), returnType);
        }
    }
}